home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.12 Dec 90 / Simulation code / CarWash.m < prev    next >
Encoding:
Text File  |  1989-06-18  |  6.2 KB  |  262 lines  |  [TEXT/MPS ]

  1. (****************************************************)
  2. (*                                                    *)
  3. (*    file:  CarWash.m                                *)
  4. (*                                                    *)
  5. (*    Car Wash simulation using SimulationToolbox.      *)
  6. (*                                                    *)
  7. (*    REFERENCE:  Goldberg and Robson, SMALLTALK-80:    *) 
  8. (*    THE LANGUAGE AND ITS IMPLEMENTATION,            *) 
  9. (*    pp. 518-521.                                    *)
  10. (*                                                    *)
  11. (*    Written in SemperSoft Modula-2 v.1.1.2            *)
  12. (*                                                    *)
  13. (*    Allen Stenger    May 1989                          *)
  14. (*                                                    *)
  15. (****************************************************)
  16.  
  17. MODULE CarWash;
  18.  
  19. FROM SYSTEM                IMPORT ADDRESS,ADR;
  20. FROM InOut                IMPORT ReadCard,Write,
  21.                                 WriteCard,WriteLn,
  22.                                 WriteString;
  23. FROM Terminal            IMPORT WritePString;
  24. FROM SimulationToolbox    IMPORT Duration,Requester,
  25.                                 SimulationQueue;
  26. FROM SimulationToolbox    IMPORT CreateNewThread,
  27.                                 CurrentTime,HaltThread,
  28.                                 HaltSimulation,Hold,
  29.                                 InitializeQueue,
  30.                                 PlaceOrder,Reactivate,
  31.                                 Serve;
  32. FROM Distributions        IMPORT ExponentialDistribution,
  33.                                 UniformDistribution;
  34.  
  35. CONST
  36.     WS                =    8192;    (* default work size *)
  37.  
  38. (*    Note:  
  39.     Times (Duration type) are in 0.01-minute units. *)
  40.     
  41.     WashArrivalMean    
  42.                 =    2000;    (* mean arrival time for 
  43.                                 wash only *)
  44.     WashAndWaxArrivalMean    
  45.                 =    3000;    (* mean arrival time for 
  46.                                 wash and wax *)
  47.     MinWashTime    =    1200;    (* min and max wash times *)
  48.     MaxWashTime    =    2600;
  49.     MinWaxTime    =    800;    (* min and max wax times *)
  50.     MaxWaxTime    =    1200;
  51.     
  52. TYPE
  53.     DesiredService    =    ( Wash, WashAndWax );
  54.     WasherParams    =    RECORD 
  55.                         (* for starting washer thread *)
  56.                             WhoAmI    :    CARDINAL;
  57.                         END; (* RECORD *)
  58.     CarParams        =    RECORD 
  59.                         (* for starting car thread *)
  60.                             WhoAmI    :    CARDINAL;
  61.                             type    :    DesiredService;
  62.                         END; (* RECORD *)
  63.     ServiceParams    =    RECORD 
  64.                     (* describes car wanting service *)
  65.                             Car        :    CARDINAL;
  66.                             Service    :    DesiredService;
  67.                         END; (* RECORD *)
  68. VAR
  69.     latestCar        :    ARRAY 
  70.                             DesiredService OF CARDINAL;
  71.                     (* numbers of last cars created *)
  72.  
  73.     CarWashEntrance    :    SimulationQueue;
  74.     timeLimit        :    Duration; (* extent of                                                 simulation *)
  75.     numberOfWashers    :    CARDINAL; 
  76.                         (* number of servers *)
  77.     
  78.  
  79. PROCEDURE LoggitWasher( washer : CARDINAL;
  80.                         s : ARRAY OF CHAR;
  81.                         type : DesiredService; 
  82.                         car : CARDINAL );
  83. BEGIN
  84.     WriteCard( CurrentTime(),6 );
  85.     Write(" ");
  86.     WriteString("Washer");    
  87.     WriteCard( washer,3 );
  88.     Write(" ");
  89.     IF type = Wash
  90.     THEN
  91.         WriteString("(Wash");
  92.     ELSE
  93.         WriteString("(WashAndWax");
  94.     END; (* IF *)
  95.     WriteCard( car,3 );
  96.     WriteString(") ");
  97.     WriteString( s );
  98.     WriteLn;
  99. END LoggitWasher;
  100.  
  101. PROCEDURE LoggitCar(     car : CARDINAL; 
  102.                         s : ARRAY OF CHAR; 
  103.                         type : DesiredService );
  104. BEGIN
  105.     WriteCard( CurrentTime(),6 );
  106.     Write(" ");
  107.     IF type = Wash
  108.     THEN
  109.         WriteString("Wash ");
  110.     ELSE
  111.         WriteString("WashAndWax ");
  112.     END; (* IF *)
  113.     WriteCard( car,3 );
  114.     Write(" ");
  115.     WriteString( s );
  116.     WriteLn;
  117. END LoggitCar;
  118.  
  119. PROCEDURE SimulateWasher( parameterAddress : ADDRESS );
  120. VAR
  121.     wpp        :    POINTER TO WasherParams;
  122.     whoAmI    :    CARDINAL; (* number of this washer *)
  123.     r        :    Requester; (* who is being served *)
  124.     sType    :    POINTER TO ServiceParams; 
  125.     service    :    DesiredService;
  126.     car    :    CARDINAL;
  127. BEGIN
  128.     wpp := parameterAddress;
  129.     whoAmI := wpp^.WhoAmI;
  130.     LOOP
  131.         Serve( CarWashEntrance, sType, r);
  132.         WITH sType^ DO
  133.             service := Service;
  134.             car := Car;
  135.         END; (* WITH *)
  136.         
  137.         (* wash car *)
  138.         LoggitWasher( whoAmI,"Washing car.",
  139.                         service,car );
  140.         Hold( UniformDistribution( 
  141.                 MinWashTime, MaxWashTime 
  142.                     ) );
  143.         LoggitWasher( whoAmI,"Wash complete.",
  144.                         service,car );
  145.         IF service = WashAndWax
  146.         THEN (* also wax car *)
  147.             LoggitWasher( whoAmI,"Waxing car.",
  148.                             service,car );
  149.             Hold( UniformDistribution( 
  150.                     MinWaxTime, MaxWaxTime ) );
  151.             LoggitWasher( whoAmI,"Wax complete.",
  152.                             service,car );
  153.         END; (* IF *)
  154.         
  155.         Reactivate( r );
  156.         LoggitWasher( whoAmI,"Ready for next car.",
  157.                         service,car );
  158.     END; (* LOOP *)
  159. END SimulateWasher;
  160.  
  161. PROCEDURE CreateNewCar( type : DesiredService ); FORWARD;
  162.  
  163. PROCEDURE SimulateCar( parameterAddress : ADDRESS );
  164. VAR
  165.     cpp        :    POINTER TO CarParams;
  166.     whoAmI    :    CARDINAL; (* number of this car *)
  167.     type    :    DesiredService;
  168.     mean    :    Duration; (* mean inter-arrival time *)
  169.     carDesc    :    ServiceParams;
  170. BEGIN
  171.     cpp := parameterAddress;
  172.     type := cpp^.type;
  173.     whoAmI := cpp^.WhoAmI;
  174.     IF whoAmI = 1 
  175.     THEN (* start running right away *)
  176.     ELSE (* delay to simulate random arrival time *)
  177.         CASE type OF
  178.             Wash        :    mean := WashArrivalMean |
  179.             WashAndWax    :    mean 
  180.                             := WashAndWaxArrivalMean;
  181.         END; (* CASE *)
  182.         Hold( ExponentialDistribution( mean ) );
  183.     END; (* IF *)
  184.     
  185.     CreateNewCar( type ); (* create next car of this
  186.                                 type *)
  187.     
  188.     LoggitCar( whoAmI,"Entering car wash entrance.",
  189.                 type );
  190.     WITH carDesc DO
  191.         Service := type;
  192.         Car := whoAmI;
  193.     END; (* WITH *)
  194.     (* queue up for service *)
  195.     PlaceOrder( CarWashEntrance, ADR(carDesc) ); 
  196.     LoggitCar( whoAmI,"Leaving car wash.",type );
  197.     
  198.     HaltThread; (* service over,
  199.                     car disappears into sunset *)
  200. END SimulateCar;
  201.  
  202. PROCEDURE CreateNewCar( type : DesiredService );
  203. VAR
  204.     cp    :    CarParams;
  205. BEGIN
  206.     IF CurrentTime() < timeLimit
  207.     THEN
  208.         INC(latestCar[type]);
  209.         cp.WhoAmI := latestCar[type];
  210.         cp.type := type;
  211.         CreateNewThread( SimulateCar,ADR(cp),WS);
  212.     ELSE
  213.         HaltSimulation;
  214.     END; (* IF *)
  215. END CreateNewCar;
  216.  
  217. PROCEDURE InitSimulation;
  218. VAR
  219.     i    :    DesiredService; (* loop control *)
  220.     n    :    CARDINAL; (* loop control *)
  221.     wp    :    WasherParams;
  222.     dur    :    CARDINAL;
  223.     
  224. BEGIN
  225.     WritePString("How many washers are there?  ");
  226.     ReadCard( numberOfWashers );
  227.     WritePString(
  228.      "How long should the simulation run (minutes) ? ");
  229.     ReadCard( dur );
  230.     timeLimit := dur * 100; 
  231.         (* Duration is in 0.01-minute units *)
  232.     WriteString("****** Simulation run with ");
  233.     WriteCard( numberOfWashers,3 );
  234.     WriteString(" washers,");
  235.     WriteLn;
  236.     WriteString("****** for a duration of ");
  237.     WriteCard( timeLimit,6 );
  238.     WriteString(".");
  239.     WriteLn;
  240.     
  241.     FOR i := MIN(DesiredService) 
  242.         TO MAX(DesiredService) DO
  243.         latestCar[i] := 0;
  244.         END; (* FOR *)
  245.     InitializeQueue( CarWashEntrance );
  246.     
  247.     (* Create all washers *)
  248.     FOR n := 1 TO numberOfWashers DO
  249.         wp.WhoAmI := n;
  250.         CreateNewThread( SimulateWasher,ADR(wp),WS );
  251.     END; (* FOR *)
  252.     
  253.     (* Create one of each kind of car *);
  254.     CreateNewCar( Wash );
  255.     CreateNewCar( WashAndWax );
  256.     
  257. END InitSimulation;
  258.  
  259. BEGIN
  260.     InitSimulation;
  261.     HaltThread;
  262. END CarWash.